﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

namespace ArithCollect {
    /*
     * Tople<T..> 采用末位索引构造，总是使用T3做为Tople<T1,T2,T3>的索引
     * 使用T8索引 Tople<T1,T2,T3,T4,T5,T6,T7,T8>的索引
     * 除了 Tople<T1,T2>的情况以外 高于2个泛型参数以上的Tople类型均可以通过
     * x[Tx]==Some(T)做为 List<Tople<T..>>的 筛选条件来用，另一方面，通过
     * 索引链表达提高了 Tople的可读性;
     * 例如：
     *     var xs = from item in list where item["身高"] > 173 select item;
            foreach (var item in xs) {
                Console.WriteLine(item);
            }
            var xs2 = from item in list select Tople.C(item.Item1, item.Item2, "xxx");
            foreach (var item in xs2) {
                Console.WriteLine(item);
            }
     *     var xs = from item in list where item["小张"] != null select item;
            Console.WriteLine("考试成绩，年龄，性别，名称");
            foreach (var item in xs) {
                Console.WriteLine(item);
            }
            var xs2 = from item in list let item2 = item as Tople<int, int, bool> where item2[true] != null select item;
            Console.WriteLine("考试成绩，年龄，性别，名称");
            foreach (var item in xs2) {
                Console.WriteLine(item);
            }
            var xs3 = from item in list let item2 = item as Tople<int, int> where item2.Item1 > 60 select item;
            Console.WriteLine("考试成绩，年龄，性别，名称");
            foreach (var item in xs3) {
                Console.WriteLine(item);
            }
     * 当然这个可读性是建立 在 一定的性能代价之上的
     * 当权衡使用，并且 避免滥用。
     * 通过对Tople添加这些特征 极大的改善了Tople的业务可读，和业务开发意义,
     * 拓展了Tople<T..>类型在业务场景 中的使用价值.
     */
    public class Tople<T1, T2, T3, T4, T5, T6, T7, T8> : Tople<T1, T2, T3, T4, T5, T6, T7> {
        public T8 Item8 { get; set; }
        public Tople(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
            : base(t1, t2, t3, t4, t5, t6, t7) {
            Item8 = t8;
        }
        public Tople(Tople<T1, T2, T3, T4, T5, T6, T7> t1, T8 t8)
            : base(t1.Item1, t1.Item2, t1.Item3, t1.Item4, t1.Item5, t1.Item6, t1.Item7) {
            Item8 = t8;
        }
        public Tople(Tople<T1, T2, T3, T4, T5, T6> t1, T7 t7, T8 t8)
            : base(t1, t7) {
            Item8 = t8;
        }
        public Tople(Tople<T1, T2, T3, T4, T5> t1, T6 t2, T7 t3, T8 t8)
            : base(t1, t2, t3) {
            Item8 = t8;
        }
        public Tople(Tople<T1, T2, T3, T4> t1, T5 t2, T6 t3, T7 t7, T8 t8)
            : base(t1, t2, t3, t7) {
            Item8 = t8;
        }
        public Tople(Tople<T1, T2, T3> t1, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
            : base(t1, t4, t5, t6, t7) {
            Item8 = t8;
        }
        public Tople(Tople<T1, T2> t1, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
            : base(t1, t3, t4, t5, t6, t7) {
            Item8 = t8;
        }
        public Tople()
            : base() {
            Item5 = default(T5);
        }
        public Tople<T1, T2, T3, T4, T5, T6, T7> this[T8 t] {
            get {
                if (Item8.Equals(t))
                    return this;
                return default(Tople<T1, T2, T3, T4, T5, T6, T7>);
            }
            set {
                if (Item8.Equals(t)) {
                    Item1 = value.Item1;
                    Item2 = value.Item2;
                    Item3 = value.Item3;
                    Item4 = value.Item4;
                    Item5 = value.Item5;
                    Item6 = value.Item6;
                    Item7 = value.Item7;
                }
            }
        }
        public override string ToString() {
            return string.Format("{0},{1}", base.ToString(), Item8.ToString());
        }
    }
    public class Tople<T1, T2, T3, T4, T5, T6, T7> : Tople<T1, T2, T3, T4, T5, T6> {
        public T7 Item7 { get; set; }
        public Tople(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
            : base(t1, t2, t3, t4, t5, t6) {
            Item7 = t7;
        }
        public Tople(Tople<T1, T2, T3, T4, T5, T6> t, T7 t7)
            : base(t.Item1, t.Item2, t.Item3, t.Item4, t.Item5, t.Item6) {
            Item7 = t7;
        }
        public Tople(Tople<T1, T2, T3, T4, T5> t1, T6 t2, T7 t7)
            : base(t1, t2) {
            Item7 = t7;
        }
        public Tople(Tople<T1, T2, T3, T4> t1, T5 t2, T6 t3, T7 t7)
            : base(t1, t2, t3) {
            Item7 = t7;
        }
        public Tople(Tople<T1, T2, T3> t1, T4 t4, T5 t5, T6 t6, T7 t7)
            : base(t1, t4, t5, t6) {
            Item7 = t7;
        }
        public Tople(Tople<T1, T2> t1, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
            : base(t1, t3, t4, t5, t6) {
            Item7 = t7;
        }
        public Tople()
            : base() {
            Item5 = default(T5);
        }
        public Tople<T1, T2, T3, T4, T5, T6> this[T7 t] {
            get {
                if (Item7.Equals(t))
                    return this;
                return default(Tople<T1, T2, T3, T4, T5, T6>);
            }
            set {
                if (Item7.Equals(t)) {
                    Item1 = value.Item1;
                    Item2 = value.Item2;
                    Item3 = value.Item3;
                    Item4 = value.Item4;
                    Item5 = value.Item5;
                    Item6 = value.Item6;
                }
            }
        }
        public override string ToString() {
            return string.Format("{0},{1}", base.ToString(), Item7.ToString());
        }
    }
    public class Tople<T1, T2, T3, T4, T5, T6> : Tople<T1, T2, T3, T4, T5> {
        public T6 Item6 { get; set; }
        public Tople(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
            : base(t1, t2, t3, t4, t5) {
            Item6 = t6;
        }
        public Tople(Tople<T1, T2, T3, T4, T5> t1, T6 t6)
            : base(t1.Item1, t1.Item2, t1.Item3, t1.Item4, t1.Item5) {
            Item6 = t6;
        }
        public Tople(Tople<T1, T2, T3, T4> t, T5 t5, T6 t6)
            : base(t, t5) {
            Item6 = t6;
        }
        public Tople(Tople<T1, T2, T3> t1, T4 t4, T5 t5, T6 t6)
            : base(t1, t4, t5) {
            Item6 = t6;
        }
        public Tople(Tople<T1, T2> t1, T3 t3, T4 t4, T5 t5, T6 t6)
            : base(t1, t3, t4, t5) {
            Item6 = t6;
        }
        public Tople()
            : base() {
            Item5 = default(T5);
        }
        public Tople<T1, T2, T3, T4, T5> this[T6 t] {
            get {
                if (Item6.Equals(t))
                    return this;
                return default(Tople<T1, T2, T3, T4, T5>);
            }
            set {
                if (Item6.Equals(t)) {
                    Item1 = value.Item1;
                    Item2 = value.Item2;
                    Item3 = value.Item3;
                    Item4 = value.Item4;
                    Item5 = value.Item5;
                }
            }
        }
        public override string ToString() {
            return string.Format("{0},{1}", base.ToString(), Item6.ToString());
        }
    }
    public class Tople<T1, T2, T3, T4, T5> : Tople<T1, T2, T3, T4> {
        public T5 Item5 { get; set; }
        public Tople(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
            : base(t1, t2, t3, t4) {
            Item5 = t5;
        }
        public Tople(Tople<T1, T2, T3, T4> t1, T5 t5)
            : base(t1.Item1, t1.Item2, t1.Item3, t1.Item4) {
            Item5 = t5;
        }
        public Tople(Tople<T1, T2, T3> t1, T4 t2, T5 t5)
            : base(t1, t2) {
            Item5 = t5;
        }
        public Tople(Tople<T1, T2> t1, T3 t2, T4 t4, T5 t5)
            : base(t1, t2, t4) {
            Item5 = t5;
        }
        public Tople()
            : base() {
            Item5 = default(T5);
        }
        public Tople<T1, T2, T3, T4> this[T5 t] {
            get {
                if (Item5.Equals(t))
                    return this;
                return default(Tople<T1, T2, T3, T4>);
            }
            set {
                if (Item5.Equals(t)) {
                    Item1 = value.Item1;
                    Item2 = value.Item2;
                    Item3 = value.Item3;
                    Item4 = value.Item4;
                }
            }
        }
        public override string ToString() {
            return string.Format("{0},{1}", base.ToString(), Item5.ToString());
        }
    }
    public class Tople<T1, T2, T3, T4> : Tople<T1, T2, T3> {
        public T4 Item4 { get; set; }
        public Tople(T1 t1, T2 t2, T3 t3, T4 t4)
            : base(t1, t2, t3) {
            Item4 = t4;
        }
        public Tople(Tople<T1, T2, T3> t1, T4 t4)
            : base(t1.Item1, t1.Item2, t1.Item3) {
            Item4 = t4;
        }
        public Tople(Tople<T1, T2> t1, T3 t2, T4 t4)
            : base(t1, t2) {
            Item4 = t4;
        }
        public Tople()
            : base() {
            Item4 = default(T4);
        }
        public Tople<T1, T2, T3> this[T4 t] {
            get {
                if (Item4.Equals(t))
                    return this;
                return default(Tople<T1, T2, T3>);
            }
            set {
                if (Item4.Equals(t)) {
                    Item1 = value.Item1;
                    Item2 = value.Item2;
                    Item3 = value.Item3;
                }
            }
        }
        public override string ToString() {
            return string.Format("{0},{1}", base.ToString(), Item4.ToString());
        }
    }
    public class Tople<T1, T2, T3> : Tople<T1, T2> {
        public T3 Item3 { get; set; }
        public Tople(T1 t1, T2 t2, T3 t3)
            : base(t1, t2) {
            Item3 = t3;
        }
        public Tople(Tople<T1, T2> t1, T3 t3)
            : base(t1.Item1, t1.Item2) {
            Item3 = t3;
        }
        public Tople()
            : base() {
            Item3 = default(T3);
        }
        public Tople<T1, T2> this[T3 t] {
            get {
                if (Item3.Equals(t)) {
                    return this;
                } return default(Tople<T1, T2>);
            }
            set {
                if (Item3.Equals(t)) {
                    this.Item1 = value.Item1;
                    this.Item2 = value.Item2;
                }
            }
        }
        public override string ToString() {
            return string.Format("{0},{1}", base.ToString(), Item3.ToString());
        }
    }
    public class Tople<T1, T2> :Tople<T1>{
        public T2 Item2 { get; set; }
        public Tople(T1 t1, T2 t2) :base(t1){
            Item2 = t2;
        }
        public Tople(Tople<T1> t,T2 t2):base(t.Item1) {
            Item2 = t2;
        }
        public Tople() {
            Item1 = default(T1);
            Item2 = default(T2);
        }
        public T2 this[T1 t1] {
            get {
                if (Item1.Equals(t1)) {
                    return Item2;
                } return default(T2);
            }
            set {
                if (Item1.Equals(t1)) {
                    Item2 = value;
                }
            }
        }
        public T1 this[T2 t2] {
            get {
                if (Item2.Equals(t2)) {
                    return Item1;
                } return default(T1);
            }
            set {
                if (Item2.Equals(t2)) {
                    Item1 = value;
                }
            }
        }
        public override string ToString() {
            return string.Format("{0},{1}", Item1.ToString(), Item2.ToString());
        }
    }

    public class Tople<T> {
        public T Item1 { get; set; }
        public Tople(T t) {
            Item1 = t;
        }
        public Tople() {
            Item1 = default(T);
        }
        public override string ToString() {
            return Item1.ToString();
        }
    }
    public static class Tople {
        public static Tople<T> C<T>(T t) {
            return new Tople<T>(t);
        }
        public static Tople<T1, T2> C<T1, T2>(T1 t1, T2 t2) {
            return new Tople<T1, T2>(t1, t2);
        }
        public static Tople<T1, T2, T3> C<T1, T2, T3>(T1 t1, T2 t2, T3 t3) {
            return new Tople<T1, T2, T3>(t1, t2, t3);
        }
        public static Tople<T1, T2, T3, T4> C<T1, T2, T3, T4>(T1 t1, T2 t2, T3 t3, T4 t4) {
            return new Tople<T1, T2, T3, T4>(t1, t2, t3, t4);
        }
        public static Tople<T1, T2, T3, T4, T5> C<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) {
            return new Tople<T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5);
        }
        public static Tople<T1, T2, T3, T4, T5, T6> C<T1, T2, T3, T4, T5, T6>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) {
            return new Tople<T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6);
        }
        public static Tople<T1, T2, T3, T4, T5, T6, T7> C<T1, T2, T3, T4, T5, T6, T7>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) {
            return new Tople<T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7);
        }
        public static Tople<T1, T2, T3, T4, T5, T6, T7, T8> C<T1, T2, T3, T4, T5, T6, T7, T8>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) {
            return new Tople<T1, T2, T3, T4, T5, T6, T7, T8>(t1, t2, t3, t4, t5, t6, t7, t8);
        }
    }
}
